﻿using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace YougeBookmark.Utils
{
    /// <summary>
    /// 剪贴板监听器（支持Windows 10+新式通知）
    /// </summary>
    public class ClipboardWatcher : NativeWindow, IDisposable
    {
        private const int WM_CLIPBOARDUPDATE = 0x031D;
        private const int WM_DESTROY = 0x0002;

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool AddClipboardFormatListener(IntPtr hwnd);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool RemoveClipboardFormatListener(IntPtr hwnd);

        /// <summary>
        /// 剪贴板内容变化事件（过滤后仅URL有效时触发）
        /// </summary>
        public event EventHandler<string> ClipboardUrlChanged;

        /// <summary>
        /// 原始剪贴板变化事件
        /// </summary>
        public event EventHandler ClipboardUpdated;

        public ClipboardWatcher()
        {
            CreateHandle(new CreateParams()); // 创建隐藏窗口
        }

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_CLIPBOARDUPDATE:
                    OnClipboardUpdate();
                    break;
                case WM_DESTROY:
                    RemoveClipboardFormatListener(Handle);
                    break;
            }
            base.WndProc(ref m);
        }

        protected override void OnHandleChange()
        {
            if (Environment.OSVersion.Version.Major >= 6) // Windows Vista+
            {
                if (!AddClipboardFormatListener(Handle))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            base.OnHandleChange();
        }

        private void OnClipboardUpdate()
        {
            try
            {
                ClipboardUpdated?.Invoke(this, EventArgs.Empty);

                if (Clipboard.ContainsText())
                {
                    var text = Clipboard.GetText();
                    if (IsValidUrl(text))
                    {
                        ClipboardUrlChanged?.Invoke(this, text);
                    }
                }
            }
            catch (ExternalException ex)
            {
                // 处理剪贴板访问冲突（代码 5）
                if (ex.ErrorCode == 5)
                {
                    // 延迟重试机制
                    System.Windows.Forms.Timer retryTimer = new System.Windows.Forms.Timer { Interval = 500 };
                    retryTimer.Tick += (s, e) => {
                        retryTimer.Stop();
                        OnClipboardUpdate();
                    };
                    retryTimer.Start();
                }
            }
        }

        private bool IsValidUrl(string input)
        {
            return Uri.TryCreate(input, UriKind.Absolute, out Uri uriResult)
                && (uriResult.Scheme == Uri.UriSchemeHttp
                    || uriResult.Scheme == Uri.UriSchemeHttps);
        }

        public void Dispose()
        {
            RemoveClipboardFormatListener(Handle);
            DestroyHandle();
            GC.SuppressFinalize(this);
        }

        ~ClipboardWatcher()
        {
            Dispose();
        }
    }
}